#include <M5Stack.h>
#include <HTTPClient.h>
#include <math.h>
#include <ArduinoJson.h>

#include "pngle.h"

#define WEATHER_0  "https://cdn.nlark.com/yuque/0/2021/png/1013239/1619322513924-8d39d7ad-2558-4775-80aa-ed2bc61dce66.png"
#define WEATHER_1  "https://cdn.nlark.com/yuque/0/2021/png/1013239/1619322513835-60507db3-4688-40b5-a9cd-4859de4a56e4.png"
#define WEATHER_2  "https://cdn.nlark.com/yuque/0/2021/png/1013239/1619322513872-7d61a2ec-297e-4ed4-b039-ac81147ed5ca.png"
#define WEATHER_3  "https://cdn.nlark.com/yuque/0/2021/png/1013239/1619322513870-36aaae3f-230b-4717-b5a8-a937978df48c.png"
#define WEATHER_4  "https://cdn.nlark.com/yuque/0/2021/png/1013239/1619322513924-80d1b83c-7aaf-4a64-80c3-e0cd93b18b61.png"
#define WEATHER_5  "https://cdn.nlark.com/yuque/0/2021/png/1013239/1619322514334-3f8e5599-faf9-4551-855f-f6cc62d203e3.png"
#define WEATHER_6  "https://cdn.nlark.com/yuque/0/2021/png/1013239/1619322514343-f48ebe31-cba6-4179-a157-4e5b2d4d12ae.png"
#define WEATHER_7  "https://cdn.nlark.com/yuque/0/2021/png/1013239/1619322514455-c13da7b9-cd30-48ad-b6ef-af0e018e8f26.png"
#define WEATHER_8  "https://cdn.nlark.com/yuque/0/2021/png/1013239/1619322514477-ee5f1465-1df0-45f6-a18d-8e341668a264.png"
#define WEATHER_9  "https://cdn.nlark.com/yuque/0/2021/png/1013239/1619322514484-9fd9584e-3d22-4dc3-8a0a-ee5972222b51.png"
#define WEATHER_10 "https://cdn.nlark.com/yuque/0/2021/png/1013239/1619322514773-6cc8758b-08fe-48cb-b769-7c6d0d10cd56.png"
#define WEATHER_11 "https://cdn.nlark.com/yuque/0/2021/png/1013239/1619322514822-ae80b7be-a988-4503-8515-f45b548d8dd9.png"
#define WEATHER_12 "https://cdn.nlark.com/yuque/0/2021/png/1013239/1619322515055-240079dc-1fcf-49c3-8284-705b55a9ffb5.png"
#define WEATHER_13 "https://cdn.nlark.com/yuque/0/2021/png/1013239/1619322515069-d7fe8530-bb74-4033-8aaf-838e8ea00cd9.png"
#define WEATHER_14 "https://cdn.nlark.com/yuque/0/2021/png/1013239/1619322515170-f7b6361a-c430-43a0-92bc-e77d4ca122ee.png"
#define WEATHER_15 "https://cdn.nlark.com/yuque/0/2021/png/1013239/1619322515257-3bb269c2-0c65-4a92-be42-8df4e4197c52.png"
#define WEATHER_16 "https://cdn.nlark.com/yuque/0/2021/png/1013239/1619322515380-ac4caa6d-2e68-457b-a016-e1b60b884064.png"
#define WEATHER_17 "https://cdn.nlark.com/yuque/0/2021/png/1013239/1619322516301-94df2c74-eb20-4671-80bc-3bfddcbfa1e4.png"
#define WEATHER_18 "https://cdn.nlark.com/yuque/0/2021/png/1013239/1619322515679-46d9b6e0-458d-4308-888a-b23cf13689f2.png"
#define WEATHER_19 "https://cdn.nlark.com/yuque/0/2021/png/1013239/1619322515788-3a4bfbf3-de34-4a3e-a6a5-b424cef191a3.png"
#define WEATHER_20 "https://cdn.nlark.com/yuque/0/2021/png/1013239/1619322515881-2a668ed4-082d-4129-8b24-66f79355f75d.png"
#define WEATHER_21 "https://cdn.nlark.com/yuque/0/2021/png/1013239/1619322516017-291c49e3-6014-47a1-b9cf-700a1129992e.png"
#define WEATHER_22 "https://cdn.nlark.com/yuque/0/2021/png/1013239/1619322516334-67913a0c-0436-4e88-baac-4262c3f47a9d.png"
#define WEATHER_23 "https://cdn.nlark.com/yuque/0/2021/png/1013239/1619322516441-ad6f5030-270d-4877-9e52-565aa8a35f80.png"
#define WEATHER_24 "https://cdn.nlark.com/yuque/0/2021/png/1013239/1619322516491-2a49cd2f-0554-4b63-81b8-8f10bb6a4d5c.png"
#define WEATHER_25 "https://cdn.nlark.com/yuque/0/2021/png/1013239/1619322516798-d02ca1b2-142b-4368-b9ed-7444e2135af1.png"
#define WEATHER_26 "https://cdn.nlark.com/yuque/0/2021/png/1013239/1619322516776-cc4d0148-d640-429d-8d6a-dee1ca60389e.png"
#define WEATHER_27 "https://cdn.nlark.com/yuque/0/2021/png/1013239/1619322516810-82cc50d8-129c-4a88-a9d1-fcc4281be7e8.png"
#define WEATHER_28 "https://cdn.nlark.com/yuque/0/2021/png/1013239/1619322516962-236feb6b-a6f3-4ae8-be10-a98c19954bb8.png"
#define WEATHER_29 "https://cdn.nlark.com/yuque/0/2021/png/1013239/1619322517080-2cc1cd8f-6a3b-4f06-9c58-fb266dbd25fb.png"
#define WEATHER_30 "https://cdn.nlark.com/yuque/0/2021/png/1013239/1619322517351-4f14defc-65d9-411a-8ff9-a273c4e0ae12.png"
#define WEATHER_31 "https://cdn.nlark.com/yuque/0/2021/png/1013239/1619322517295-36b5ec42-5157-41cd-bd59-715075a13208.png"
#define WEATHER_32 "https://cdn.nlark.com/yuque/0/2021/png/1013239/1619322517532-bf49e806-2e6f-4496-86c5-a13208c022fa.png"
#define WEATHER_33 "https://cdn.nlark.com/yuque/0/2021/png/1013239/1619322517488-59030409-ffbd-4f94-b0ba-a3984f6f233e.png"
#define WEATHER_34 "https://cdn.nlark.com/yuque/0/2021/png/1013239/1619322517670-dd633d28-9b6c-43de-9a6f-a120fad9d856.png"
#define WEATHER_35 "https://cdn.nlark.com/yuque/0/2021/png/1013239/1619322517791-6968fa92-7382-489f-91dc-31131c57850f.png"
#define WEATHER_36 "https://cdn.nlark.com/yuque/0/2021/png/1013239/1619322517908-0dfc7d9e-0d13-49c5-9e17-167571d62456.png"
#define WEATHER_37 "https://cdn.nlark.com/yuque/0/2021/png/1013239/1619322518040-766e01dc-1532-4f57-8275-88777deeb017.png"
#define WEATHER_38 "https://cdn.nlark.com/yuque/0/2021/png/1013239/1619322518031-14f319d2-5a5f-4f0a-af96-41ad800a2ccf.png"
#define WEATHER_99 "https://cdn.nlark.com/yuque/0/2021/png/1013239/1619322518462-422e9768-739f-4686-8daa-418c53f613f8.png"

//#define WIFI_SSID "Mi 11"
//#define WIFI_PASS "123456789"

#define WIFI_SSID "MagicoeSSID"
#define WIFI_PASS "fluffyskates079"

const char *host = "api.seniverse.com";
const char *privateKey = "SbiDME8QHMpPNcLux";
const char *city = "shanghai";
const char *language = "en";

struct WetherData
{
    char city[32];
    char weather[64];
    char high[32];
    char low[32];
    char humi[32];
};

void cls()
{
  M5.Lcd.fillScreen(TFT_BLACK);

  M5.Lcd.setCursor(0, 0);
  M5.Lcd.setTextColor(WHITE);
  M5.Lcd.setTextSize(1);
}

// ===================================================
// pngle example for m5stack
// ===================================================

double g_scale = 1.0;
void pngle_on_draw(pngle_t *pngle, uint32_t x, uint32_t y, uint32_t w, uint32_t h, uint8_t rgba[4])
{
  uint16_t color = (rgba[0] << 8 & 0xf800) | (rgba[1] << 3 & 0x07e0) | (rgba[2] >> 3 & 0x001f);

  if (rgba[3]) {
    x = ceil(x * g_scale);
    y = ceil(y * g_scale);
    w = ceil(w * g_scale);
    h = ceil(h * g_scale);
    M5.Lcd.fillRect(x, y, w, h, color);
  }
}

char http_buf[2048];

void load_png(const char *url, double scale = 1.0)
{
  HTTPClient http;

  http.begin(url);

  int httpCode = http.GET();
  if (httpCode != HTTP_CODE_OK) {
    M5.Lcd.printf("HTTP ERROR: %d\n", httpCode);
    http.end();
    return ;
  }

  WiFiClient *stream = http.getStreamPtr();

  pngle_t *pngle = pngle_new();
  pngle_set_draw_callback(pngle, pngle_on_draw);
  g_scale = scale; // XXX:

  memset(http_buf, 0x00, 2048);
  int remain = 0;
  while (http.connected()) {
    size_t size = stream->available();
    if (!size) { delay(1); continue; }

    if (size > sizeof(http_buf) - remain) {
      size = sizeof(http_buf) - remain;
    }

    int len = stream->readBytes(http_buf + remain, size);
    if (len > 0) {
      int fed = pngle_feed(pngle, http_buf, remain + len);
      if (fed < 0) {
        cls();
        M5.Lcd.printf("ERROR: %s\n", pngle_error(pngle));
        break;
      }

      remain = remain + len - fed;
      if (remain > 0) memmove(http_buf, http_buf + fed, remain);
    } else {
      delay(1);
    }
  }

  pngle_destroy(pngle);

  http.end();
}

void parseUserData(String content)  // Json数据解析并串口打印
{

  DynamicJsonDocument doc(512);
  DeserializationError error = deserializeJson(doc, content);

  if (error) {
    M5.Lcd.print(F("deserializeJson() failed: "));
    M5.Lcd.println(error.f_str());
    return;
  }
  JsonObject results_0 = doc["results"][0];

  JsonObject results_0_location = results_0["location"];
  const char* results_0_location_name = results_0_location["name"]; // City Information, like shanghai

  JsonObject results_0_now = results_0["now"];
  const char* results_0_now_text = results_0_now["text"]; // "Cloudy"天气状况
  const char* results_0_now_code = results_0_now["code"]; // "4"风力大小
  const char* results_0_now_temperature = results_0_now["temperature"]; // "31"温度

  M5.Lcd.println(results_0_location_name);//通过串口打印出需要的信息
  M5.Lcd.println(results_0_now_text);
  M5.Lcd.println(results_0_now_code);
  M5.Lcd.println(results_0_now_temperature);
  M5.Lcd.print("\\r\\n");

  String weather_status;
  weather_status = String(results_0_now_text);

  int i =0;
//  results_0_now_code = "0";
 // while(1)
  String now_code = String(results_0_now_code);

  while(1)
  {
    
    if(i >= 100) i = 0;
    if(i == 39)  i = 99;
    now_code = String(i);
    i++;
    M5.Lcd.fillScreen(BLACK);    //Fill the screen with red
  if(now_code == "0")       load_png(WEATHER_0);
  if(now_code == "1")       load_png(WEATHER_1);
  if(now_code == "2")       load_png(WEATHER_2);
  if(now_code == "3")       load_png(WEATHER_3);
  if(now_code == "4")       load_png(WEATHER_4);
  if(now_code == "5")       load_png(WEATHER_5);
  if(now_code == "6")       load_png(WEATHER_6);
  if(now_code == "7")       load_png(WEATHER_7);
  if(now_code == "8")       load_png(WEATHER_8);
  if(now_code == "9")       load_png(WEATHER_9);
  if(now_code == "10")      load_png(WEATHER_10);
  if(now_code == "11")      load_png(WEATHER_11);
  if(now_code == "12")      load_png(WEATHER_12);
  if(now_code == "13")      load_png(WEATHER_13);
  if(now_code == "14")      load_png(WEATHER_14);
  if(now_code == "15")      load_png(WEATHER_15);
  if(now_code == "16")      load_png(WEATHER_16);
  if(now_code == "17")      load_png(WEATHER_17);
  if(now_code == "18")      load_png(WEATHER_18);
  if(now_code == "19")      load_png(WEATHER_19);
  if(now_code == "20")      load_png(WEATHER_20);
  if(now_code == "21")      load_png(WEATHER_21);
  if(now_code == "22")      load_png(WEATHER_22);
  if(now_code == "23")      load_png(WEATHER_23);
  if(now_code == "24")      load_png(WEATHER_24);
  if(now_code == "25")      load_png(WEATHER_25);
  if(now_code == "26")      load_png(WEATHER_26);
  if(now_code == "27")      load_png(WEATHER_27);
  if(now_code == "28")      load_png(WEATHER_28);
  if(now_code == "29")      load_png(WEATHER_29);
  if(now_code == "30")      load_png(WEATHER_30);
  if(now_code == "31")      load_png(WEATHER_31);
  if(now_code == "32")      load_png(WEATHER_32);
  if(now_code == "33")      load_png(WEATHER_33);
  if(now_code == "34")      load_png(WEATHER_34);
  if(now_code == "35")      load_png(WEATHER_35);
  if(now_code == "36")      load_png(WEATHER_36);
  if(now_code == "37")      load_png(WEATHER_37);
  if(now_code == "38")      load_png(WEATHER_38);
  if(now_code == "99")      load_png(WEATHER_99);
    delay(10);
  }


}
// ===================================================

void setup()
{
  M5.begin();

  M5.Lcd.printf("Welcome.\n");

  WiFi.begin(WIFI_SSID, WIFI_PASS);
  while (WiFi.status() != WL_CONNECTED) {
    delay(100);
    M5.Lcd.print(".");
  }

  M5.Lcd.printf("WiFi connected.\n");
  
  HTTPClient http;

  http.begin("https://api.seniverse.com/v3/weather/now.json?key=SbiDME8QHMpPNcLux&location=shanghai&language=en&unit=c");

  int httpCode = http.GET();
  if (httpCode != HTTP_CODE_OK) {
    M5.Lcd.printf("HTTP ERROR: %d\n", httpCode);
    http.end();
    return ;
  }
  
  WiFiClient *stream = http.getStreamPtr();

  int remain = 0;
  size_t size;
  int len = 0;
  memset(http_buf, 0x00, 2048);
  while (http.connected())
  {
    size = stream->available();
    if (!size) { delay(1); continue; }

    if (size > sizeof(http_buf) - remain) {
      size = sizeof(http_buf) - remain;
    }

    len += stream->readBytes(http_buf + remain, size);
    if (len > 0) {
      remain = remain + len;
    } else {
      delay(1);
    }
  }
  M5.Lcd.printf("Received %d\n", len);
  M5.Lcd.printf("%s\n", http_buf);
  http.end();
  String reportdata;
  reportdata = String(http_buf);
  if(len > 0)
  {
    parseUserData(reportdata);
  }
  WiFi.disconnect();
}

void loop()
{
  M5.update();

  if (M5.BtnA.wasReleased()) {
 //   load_png("https://cdn.nlark.com/yuque/0/2021/png/1013239/1619322513924-8d39d7ad-2558-4775-80aa-ed2bc61dce66.png");
  } else if (M5.BtnB.wasReleased()) {
 //   load_png("http://gitee.com/magicoe/m5-stack_/raw/master/images/white/1@1x.png");
  } else if (M5.BtnC.wasReleased()) {
 //   load_png("http://gitee.com/magicoe/m5-stack_/raw/master/images/white/2@1x.png");
  }
}
